home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / vballs11.zip / BALLS2.C < prev    next >
C/C++ Source or Header  |  1991-03-06  |  5KB  |  277 lines

  1. /*
  2.  * balls2.c - Attempt to draw balls in VGA256 mode
  3.  *
  4.  *             Uses BGI interface
  5.  *
  6.  * Adapted by: Scott J. Walter (GEnie:  S.Walter4)
  7.  *            
  8.  */
  9.  
  10. /* INCLUDES */
  11.  
  12. #include <stdio.h>
  13. #include <dos.h>
  14. #include <math.h>
  15. #include <graphics.h>
  16. #include <stdlib.h>
  17. #include <conio.h>
  18. #include <alloc.h>
  19. #include <bios.h>
  20. #include <time.h>
  21.  
  22.  
  23.  
  24. /* DEFINES */
  25.  
  26. #define DIM   3                /* number of dimensions        */
  27. #define TRUE  1
  28. #define FALSE 0
  29.  
  30. typedef unsigned char UBYTE;
  31.  
  32. typedef double VECTOR [DIM];
  33.  
  34. typedef struct {
  35.            UBYTE Rvalue;
  36.            UBYTE Gvalue;
  37.            UBYTE Bvalue;
  38.            } ColorValue;
  39.  
  40.  
  41.  
  42. /* PROTOTYPES */
  43.  
  44. int huge DetectVGA256(void);
  45. void     VGASetAllPalette(UBYTE far *pal);
  46. void     Hsi2Rgb(float H, float S, float I, ColorValue *C);
  47. void     normalize (VECTOR this_vec);
  48. double   dot_prod (VECTOR vec1, VECTOR vec2);
  49. void     put_atom(int R, int index, int xc, int yc, VECTOR l_source);
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56. void put_atom(int R, int index, int xc, int yc, VECTOR l_source)
  57. {
  58.  VECTOR s_point;
  59.  int R2, color = 0;
  60.  double x,y,z,r,intensity;
  61.  
  62.  
  63.  normalize(l_source);               /* normalize the light source    */
  64.  R2=R*R;                            /* only calculate R*R once     */
  65.  for (x=-R;x<=+R;x=x+1)             /* scan an area 2R x 2R     */
  66.   {
  67.   for (y=-R;y<=+R;y=y+1)
  68.    {
  69.    r=(x*x)+(y*y);             /* check that the pixel is within a     */
  70.    if (r <= R2)               /* circle of radius R               */
  71.     {
  72.     z=sqrt((R2)-r);            /* calculate the altitude of the point     */
  73.     s_point[0]= x;             /* set the normal surface vector to the */
  74.     s_point[1]= y;             /* coordinates of the point         */
  75.     s_point[2]= z;
  76.  
  77.     intensity  = random(100);
  78.     intensity /= 100;
  79.  
  80.     intensity += 64 * dot_prod(s_point,l_source)/R;
  81.  
  82.     color = (int)intensity;
  83.  
  84.     color = color<0 ? 0 : (color> 63 ? 63 : color);
  85.  
  86.     putpixel(x+xc,y+yc,index*64 + color);
  87.     }
  88.    }
  89.   }
  90. }
  91.  
  92.  
  93.  
  94. /*
  95.  * Normalize a vector to unit magnitude.  Calculate the magnitude as:
  96.  *
  97.  *     magnitude = sqrt ( x^2 + y^2 + z^2 )
  98.  *
  99.  * Normalize the vector by dividing each coordinate by the magnitude.
  100.  * FOR loops are used to maintain generality--any dimension vector may
  101.  * be normalized by changing DIM.
  102.  */
  103. void normalize (VECTOR this_vec)
  104. {
  105.  double mag;
  106.  int count;
  107.  
  108.  
  109.  mag = 0.0;
  110.  
  111.  for (count = 0; count < DIM; count++)
  112.   mag = mag + (this_vec [count] * this_vec [count]);
  113.  
  114.  mag = sqrt(mag);
  115.  
  116.  for (count = 0; count < DIM; count++)
  117.   this_vec [count] = this_vec [count]/mag;
  118. }
  119.  
  120.  
  121.  
  122. /* Calculate the cosine of the angle between two vectors.
  123.  *
  124.  *     dot product = (x1 * x2) + (y1 * y2) + (z1 * z2)
  125.  */
  126. double dot_prod (VECTOR vec1, VECTOR vec2)
  127. {
  128.  double COSINE;
  129.  int count;
  130.  
  131.  
  132.  COSINE = 0.0;
  133.  
  134.  for (count = 0; count < DIM; count++)
  135.   COSINE += vec1 [count] * vec2 [count];
  136.  
  137.  return (COSINE);
  138. }
  139.  
  140.  
  141.  
  142. void VGASetAllPalette(pal)
  143. UBYTE far *pal;
  144. {
  145.  struct REGPACK r;
  146.  
  147.  
  148.  r.r_ax = 0x1012;
  149.  r.r_bx = 0x0000;
  150.  r.r_cx = 0x0100;
  151.  r.r_es = FP_SEG(pal);
  152.  r.r_dx = FP_OFF(pal);
  153.  
  154.  intr(0x10, &r);
  155. }
  156.  
  157.  
  158.  
  159. void Hsi2Rgb(float H, float S, float I, ColorValue *C)
  160. {
  161.  float T, Rv, Gv, Bv;
  162.  float Pi = 3.14159265358979;
  163.  
  164.  
  165.  if(H<0.0)
  166.   H = 1.0 + H;
  167.  
  168.  if(H>1.0)
  169.   H = H - 1.0;
  170.  
  171.  T  = 2.0 * Pi * H;
  172.  
  173.  Rv = 1 + S * sin(T - 2 * Pi / 3);
  174.  Gv = 1 + S * sin(T);
  175.  Bv = 1 + S * sin(T + 2 * Pi / 3);
  176.  
  177.  T = 63.999 * I / 2;
  178.  
  179.  C->Rvalue = (UBYTE)(Rv * T);
  180.  C->Gvalue = (UBYTE)(Gv * T);
  181.  C->Bvalue = (UBYTE)(Bv * T);
  182. }
  183.  
  184.  
  185.  
  186. int huge DetectVGA256()
  187. {
  188.  int gdriver, gmode;
  189.  
  190.  
  191.  detectgraph(&gdriver, &gmode);
  192.  
  193.  if((gdriver==VGA)||(gdriver==MCGA))
  194.    return 0;                    /* Default video mode = 0 */
  195.  else
  196.    return grError;             /* Couldn't detect hardware */
  197. }
  198.  
  199.  
  200.  
  201.  
  202. /* MAIN */
  203.  
  204. void main()
  205. {
  206.  int   Y, Z, ErrorCode, Driver = DETECT, Mode;
  207.  int radius  = 40;
  208.  VECTOR light = { -2.0, -2.0, 3.0 };    /* light source from upper left */
  209.  UBYTE far *pal;
  210.  float off, hue;
  211.  ColorValue C;
  212.  
  213.  
  214.  installuserdriver("VGA256", DetectVGA256);
  215.  
  216.  initgraph(&Driver, &Mode, "");
  217.  
  218.  ErrorCode = graphresult();
  219.  
  220.  if(ErrorCode!=grOk)
  221.   {
  222.   printf("Error: %s\n", grapherrormsg(ErrorCode));
  223.   exit(1);
  224.   }
  225.  
  226.  randomize();
  227.  
  228.  pal = (UBYTE far *)farmalloc(768);
  229.  
  230.  for(Y=0;Y<5;Y++)
  231.   for(Z=0;Z<64;Z++)
  232.    {
  233.    Hsi2Rgb(0.25+(float)Y/5.0, 1.0, (float)Z/64.0, &C);
  234.  
  235.    *(pal+Y*192+Z*3+0) = C.Rvalue;
  236.    *(pal+Y*192+Z*3+1) = C.Gvalue;
  237.    *(pal+Y*192+Z*3+2) = C.Bvalue;
  238.    }
  239.  
  240.  VGASetAllPalette(pal);
  241.  
  242.  for(Y=0;Y<2;Y++)
  243.   for(Z=0;Z<2;Z++)
  244.    put_atom(radius, Y*2+Z, 80+160*Z, 50+100*Y, light);
  245.  
  246.  off = 0.30;
  247.  
  248.  do
  249.   {
  250.   for(Y=0;Y<5;Y++)
  251.    for(Z=0;Z<64;Z++)
  252.     {
  253.     hue = off+(float)Y/5.0;
  254.     if(hue>1.0)
  255.      hue = hue - 1.0;
  256.  
  257.     Hsi2Rgb(hue, 1.0, (float)Z/64.0, &C);
  258.  
  259.     *(pal+Y*192+Z*3+0) = C.Rvalue;
  260.     *(pal+Y*192+Z*3+1) = C.Gvalue;
  261.     *(pal+Y*192+Z*3+2) = C.Bvalue;
  262.     }
  263.  
  264.   VGASetAllPalette(pal);
  265.  
  266.   off += 0.05;
  267.   if(off>1.0)
  268.    off = off - 1.0;
  269.   } while(!bioskey(1));
  270.  
  271.  getch();
  272.  
  273.  farfree((void far *)pal);
  274.  
  275.  closegraph();
  276. }
  277.